package com.cfweb.controller;

import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpSession;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.cfweb.api.OauthApi;
import com.cfweb.dao.CfTargetMapper;
import com.cfweb.dao.CfUserMapper;
import com.cfweb.domain.CfTarget;
import com.cfweb.domain.CfTargetExample;
import com.cfweb.domain.CfUser;
import com.cfweb.domain.CfUserExample;
import com.cfweb.pojo.OauthToken;
import com.cfweb.util.ExtJSResponse;
import com.cfweb.util.StringUtil;

/**
 * action when login system and cloudfoundry
 * write into session
 * 
 * @author lmx
 * 
 */
@Service
@Path("/login")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class LoginHandler {

	Logger logger = Logger.getLogger(LoginHandler.class);
	
	public static final String USERNAME = "username";
	public static final String REFRESH_TOKEN = "refresh_token";
	public static final String USERID = "userid";
	public static final String CLIENT = "client";
	public static final String PASSWORD = "password";
	public static final String TARGET = "target";
	public static final String TOKEN = "token";
	public static final String ORG = "org";
	public static final String SPACE = "space";
	public static final String USERIDPRIMARY = "user_primaryid";
	public static final String USERISADMIN = "userIsAdmin";

	@Autowired
	private HttpSession session;

	@Autowired
	private CfUserMapper userMapper;

	@Autowired
	private CfTargetMapper targetMapper;
	
	/**
	 * login:
	 * <b>attention: not encrypt</b>
	 * 
	 * @param username
	 * @param pass
	 * @return
	 * @throws Exception 
	 */
	@Path("/checkLogin")
	@GET
	public ExtJSResponse checkLogin(
			@QueryParam("loginName") final String username,
			@QueryParam("password") final String pass,
			@QueryParam("org") final String org,
			@QueryParam("oldOrg") final String oldOrg,
			@QueryParam("space") final String space,
			@QueryParam("oldSpace") final String oldSpace,
			@QueryParam("target") final String targetName) throws Exception {
		Map<String, Object> param = new HashMap<String, Object>();
		try {
			if (StringUtil.isEmpty(username) && StringUtil.isEmpty(pass)) {
				session.setAttribute(ORG, org);
				session.setAttribute(SPACE, space);
				
			} else {
				//获取cfttarget
				CfTargetExample cfTargetExample=new CfTargetExample();
				cfTargetExample.createCriteria().andNameEqualTo(targetName);
				URL targetUrl = getTargetURL(targetMapper.selectByExample(cfTargetExample).get(0).getTarget());
				//获取cfuser
				CfUserExample example = new CfUserExample();
				example.createCriteria().andUserNameEqualTo(username)
						.andUserPassEqualTo(pass);
				List<CfUser> cfuserList = userMapper.selectByExample(example);
				if (cfuserList != null && cfuserList.size() >= 1) {
					CfUser cfuser = cfuserList.get(0);
					session.setAttribute(ORG, cfuser.getLastOrg());
					session.setAttribute(SPACE, cfuser.getLastSpace());
					session.setAttribute(TARGET, targetUrl);
					session.setAttribute(USERID, cfuser.getUuid());
					OauthToken token=OauthApi.login(username, pass,session);
					session.setAttribute(TOKEN,token);
					session.setAttribute(USERNAME,username);
					session.setAttribute(USERIDPRIMARY, cfuser.getId() );
					session.setAttribute(USERISADMIN, cfuser.getUserIsadmin());
				} else {
					param.put("logined", false);
					session.invalidate();
				}
//				username = admin
//				userIsAdmin = 1
//				token = com.cfweb.pojo.OauthToken@48c14735
//				userid = 9724436f-5faf-4ac4-a65c-d848c9044c0a
//				target = http://api.yjs.cf
//				space = space11
//				org = org1
//				user_primaryid = 1
			}

		} catch (Exception e) {
			if(oldOrg!=null){
				session.setAttribute(ORG,oldOrg);
			}
			if(oldSpace!=null){
				session.setAttribute(SPACE,oldSpace);
			}
			throw e;
		}
		return ExtJSResponse.successResWithData(param);
	}

	/**
	 * logout
	 */
	@Path("/logout")
	@GET
	public ExtJSResponse logout() {
		try {
			CfUserExample ex = new CfUserExample();
			ex.createCriteria().andUserNameEqualTo((String)session.getAttribute(USERNAME));
			CfUser cfuser = userMapper.selectByExample(ex).get(0);
			cfuser.setLastOrg((String)session.getAttribute(ORG));
			cfuser.setLastSpace((String)session.getAttribute(SPACE));
			userMapper.updateByPrimaryKey(cfuser);

			session.invalidate();
			logger.info("Logout:" + new Date()
					+ (String)session.getAttribute(USERNAME)
					+ "is logged out.");
		} catch (Exception e) {
			logger.error(e);
			return ExtJSResponse.errorRes();
		}
		return ExtJSResponse.successRes();
	}

	/**
	 * get current user
	 * 
	 * @return
	 */
	@Path("/getCurrentUser")
	@GET
	public ExtJSResponse getCurrentUser() {
		ExtJSResponse response=ExtJSResponse.successRes();
		response.put(USERNAME, (String) session.getAttribute(USERNAME));
		response.put(ORG, (String) session.getAttribute(ORG));
		response.put(SPACE, (String) session.getAttribute(SPACE));
		response.put(USERIDPRIMARY, (Integer)session.getAttribute(USERIDPRIMARY));
		response.put(USERISADMIN, (Integer)session.getAttribute(USERISADMIN));
		return response;
	}


	/**
	 * get URL
	 * 
	 * @param target
	 * @return
	 */
	private static URL getTargetURL(String target) {
		try {
			return URI.create(target).toURL();
		} catch (MalformedURLException e) {
			throw new RuntimeException("The target URL is not valid: "
					+ e.getMessage());
		}
	}


	
	/**
	 * get target of all clouds
	 */
	@Path("/getAllCloud")
	@GET
	public ExtJSResponse getAllCloud(){
		List<CfTarget> lctar = null;
		List<String> targetNames = new ArrayList<String>();
		try{
			CfTargetExample tarexp = new CfTargetExample();
			tarexp.createCriteria().andIdIsNotNull();
			lctar = targetMapper.selectByExample(tarexp);
			for(int i = 0;i<lctar.size();i++){
				targetNames.add(lctar.get(i).getName());
			}
		}catch(Exception e){
			e.printStackTrace();
			logger.error(e);
			return ExtJSResponse.errorRes();
		}
		return ExtJSResponse.successResWithData(targetNames);
	}
	
	@Path("/currentCloud")
	@GET
	public ExtJSResponse getCurrentCloud(){
		CfTarget cfTarget = targetMapper.selectByTarget(session.getAttribute(TARGET).toString());
		return ExtJSResponse.successResWithData(cfTarget.getName());
	}
}
